import axios from 'axios'
import type { 
  AxiosInstance,AxiosRequestConfig,
  AxiosResponse,
  InternalAxiosRequestConfig,
  AxiosProgressEvent } from 'axios'
import type { RequestConfig, ResponseData, ApiError, UploadProgressCallback } from '@/types/api'
import { useAuthStore } from '@/stores/auth'

class HttpClient {
  private instance: AxiosInstance
  private readonly baseURL: string

  constructor(baseURL?: string) {
    this.baseURL = baseURL || import.meta.env.VITE_API_BASE_URL || '/api'
    
    this.instance = axios.create({
      baseURL: this.baseURL,
      timeout: 30000, // 30秒超时
      withCredentials: false, // 根据后端配置调整
      headers: {
        'Content-Type': 'application/json;charset=UTF-8'
      }
    })

    this.setupInterceptors()
  }

  // 设置拦截器
  private setupInterceptors(): void {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        return this.handleRequest(config)
      },
      (error: any) => {
        return Promise.reject(this.normalizeError(error))
      }
    )

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        return this.handleResponse(response)
      },
      (error: any) => {
        return Promise.reject(this.handleError(error))
      }
    )
  }

  // 处理请求
  private handleRequest(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
    // 添加认证 token
    const authStore = useAuthStore()
    if (authStore.token && config.headers) {
      config.headers.Authorization = `Bearer ${authStore.token}`
    }

    // 添加时间戳防止缓存（GET请求）
    if (config.method?.toUpperCase() === 'GET' && config.params) {
      config.params = {
        ...config.params,
        _t: Date.now()
      }
    }

    // 开发环境打印请求日志
    if (import.meta.env.DEV) {
      // console.log(`🚀 [API Request] ${config.method?.toUpperCase()} ${config.url}`, {
      //   data: config.data,
      //   params: config.params
      // })
    }

    return config
  }

  // 处理响应
  private handleResponse(response: AxiosResponse): any {
    const { data, config } = response
    // 开发环境打印响应日志
    if (import.meta.env.DEV) {
      console.log(`✅ [API Response] ${config.method?.toUpperCase()} ${config.url}`, data)
    }

    // 如果是文件下载等特殊响应，直接返回
    if (response.config.responseType === 'blob' || 
        response.config.responseType === 'arraybuffer') {
      return data
    }

    // 根据后端返回结构处理
    if (data && typeof data === 'object') {
      // 如果后端返回了标准的 code/message/data 结构
      if ('code' in data) {
        if (data.code === 200 || data.code === 400) {
          return data
        } else {
          throw this.createError(data)
        }
      }
      
      // 如果没有标准结构，直接返回数据
      return data
    }

    return data
  }

  // 处理错误
  private handleError(error: any): ApiError {
    // 开发环境打印错误日志
    if (import.meta.env.DEV) {
      console.error('❌ [API Error]', error)
    }

    if (error.response) {
      const { status, data } = error.response
      
      switch (status) {
        case 400:
          return this.createError({
            code: 400,
            message: data?.message || '请求参数错误'
          })
        
        case 401:
          this.handleUnauthorized()
          return this.createError({
            code: 401,
            message: '未授权，请重新登录'
          })
        
        case 403:
          return this.createError({
            code: 403,
            message: '拒绝访问'
          })
        
        case 404:
          return this.createError({
            code: 404,
            message: '请求的资源不存在'
          })
        
        case 408:
          return this.createError({
            code: 408,
            message: '请求超时'
          })
        
        case 500:
          return this.createError({
            code: 500,
            message: '服务器内部错误'
          })
        
        case 502:
          return this.createError({
            code: 502,
            message: '网关错误'
          })
        
        case 503:
          return this.createError({
            code: 503,
            message: '服务不可用'
          })
        
        case 504:
          return this.createError({
            code: 504,
            message: '网关超时'
          })
        
        default:
          return this.createError({
            code: status,
            message: data?.message || `请求失败 (${status})`
          })
      }
    } else if (error.request) {
      return this.createError({
        code: -1,
        message: '网络错误，请检查网络连接'
      })
    } else {
      return this.createError({
        code: -2,
        message: error.message || '请求配置错误'
      })
    }
  }

  // 规范化错误
  private normalizeError(error: any): ApiError {
    if (error.code && error.message) {
      return error as ApiError
    }
    
    return this.createError({
      code: -3,
      message: '未知错误'
    })
  }

  // 处理未授权
  private handleUnauthorized(): void {
    const authStore = useAuthStore()
    authStore.logout()
    
    // 跳转到登录页
    const currentPath = window.location.pathname + window.location.search
    if (window.location.pathname !== '/login') {
      window.location.href = `/login?redirect=${encodeURIComponent(currentPath)}`
    }
  }

  // 创建错误对象
  private createError(errorInfo: any): ApiError {
    return {
      code: errorInfo.code || -1,
      message: errorInfo.message || '未知错误',
      data: errorInfo.data
    }
  }

  // 公共请求方法
  public async request<T = any>(config: RequestConfig): Promise<ResponseData<T>> {
    try {
      const axiosConfig: AxiosRequestConfig = {
        url: config.url,
        method: config.method,
        data: config.data,
        params: config.params,
        headers: config.headers,
        timeout: config.timeout,
        withCredentials: config.withCredentials,
        responseType: config.responseType
      }

      const response = await this.instance.request<any>(axiosConfig)
      return response // ✅ 修改此处：返回 response.data 而不是 response
    } catch (error) {
      throw this.normalizeError(error)
    }
  }

  // GET 请求
  public async get<T = any>(url: string, params?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'params'>): Promise<ResponseData<T>> {
    return this.request<T>({
      url,
      method: 'GET',
      params,
      ...config
    })
  }

  // POST 请求
  public async post<T = any>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'data'>): Promise<ResponseData<T>> {
    return this.request<T>({
      url,
      method: 'POST',
      data,
      ...config
    })
  }

  // PUT 请求
  public async put<T = any>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'data'>): Promise<ResponseData<T>> {
    return this.request<T>({
      url,
      method: 'PUT',
      data,
      ...config
    })
  }

  // DELETE 请求
  public async delete<T = any>(url: string, params?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'params'>): Promise<ResponseData<T>> {
    return this.request<T>({
      url,
      method: 'DELETE',
      params,
      ...config
    })
  }

  // PATCH 请求
  public async patch<T = any>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'data'>): Promise<ResponseData<T>> {
    return this.request<T>({
      url,
      method: 'PATCH',
      data,
      ...config
    })
  }

  // 导出 请求
  public async export<T = any>(url: string, params?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'params'>): Promise<any> {
    return this.request<T>({
      url,
      method: 'GET',
      params,
      ...config
    })
  }

  // 文件上传
  public async upload<T = any>(
    url: string, 
    formData: FormData, 
    onProgress?: UploadProgressCallback,
    config?: Omit<RequestConfig, 'url' | 'method' | 'data'>
  ): Promise<ResponseData<T>> {
    return this.request<T>({
      url,
      method: 'POST',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data',
        ...config?.headers
      },
      onUploadProgress: (progressEvent: AxiosProgressEvent) => {
        if (onProgress && progressEvent.total) {
          const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
          onProgress(progress)
        }
      },
      ...config
    })
  }

  // 文件下载
  public async download(url: string, params?: any, filename?: string): Promise<void> {
    try {
      const response = await this.instance({
        url,
        method: 'GET',
        params,
        responseType: 'blob'
      })

      // 创建 blob 链接并下载
      const blob = new Blob([response.data])
      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = downloadUrl
      
      // 从响应头获取文件名或使用传入的文件名
      let finalFilename = filename
      const contentDisposition = response.headers['content-disposition']
      if (contentDisposition && !finalFilename) {
        const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)
        if (filenameMatch && filenameMatch[1]) {
          finalFilename = filenameMatch[1].replace(/['"]/g, '')
        }
      }
      
      link.download = finalFilename || 'download'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(downloadUrl)
    } catch (error) {
      throw this.normalizeError(error)
    }
  }

  // 取消请求
  public cancelRequest(cancelToken: any): void {
    if (cancelToken && typeof cancelToken === 'function') {
      cancelToken('请求已取消')
    }
  }

  // 获取取消令牌
  public getCancelToken() {
    return axios.CancelToken.source()
  }
}

// 创建全局实例
export const http = new HttpClient()

export default HttpClient